package cda;

import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
　* @description: 更新CDA.xlsx
　* @author jzh
　* @date 2024/7/9 下午2:52
　*/
public class UpdateExcel {
    public static void main(String[] args) {

//        // TODO 待处理Excel路径
//        String excelPath = "D:\\Desktop\\输血记录.xlsx";
//
//        // 更新属性
//        List<String> sheetNames = Arrays.asList("入院评估", "24h内入出院记录", "24h内入院死亡记录", "中医住院病案首页");
//        List<String> sheetNames = Arrays.asList("Sheet1");
//        sheetNames.forEach(sheetName -> updateAttributes(FileUtil.file(excelPath), sheetName));

        // 查所有需要配置字段的元素
        // TODO 配置参数
        String excelPath = "E:\\cda页面导出 - 副本.xlsx";
        String CDAMapPath = "E:\\cda路径映射配置 - 副本.xlsx";
        List<String> sheetNames = Arrays.asList("入院评估", "24h内入出院记录", "24h内入院死亡记录", "中医住院病案首页");

//        HashSet<String> needFields = new HashSet<>();
//        sheetNames.forEach(sheetName -> findNeedField(FileUtil.file(excelPath), sheetName, needFields));
//        // 读已配置的描述
//        HashSet<String> CDAMaps = readCDAMap(FileUtil.file(CDAMapPath), "Sheet1");
//        // 获取增加的描述
//        HashSet<String> increment = getIncrement(needFields, CDAMaps);
//        // 将增加的描述追加到文件中
//        appendToCDAMap(increment, FileUtil.file(CDAMapPath), "increment");

        // ----------------等手动配置完毕后执行此步骤----------------
        // 将追加的映射更新到指定sheet中
        updateMapToSheet(FileUtil.file(CDAMapPath), FileUtil.file(excelPath), sheetNames);

    }

    private static void updateMapToSheet(File cdaMapFile, File excelFile, List<String> sheetNames) {

        ExcelReader reader = ExcelUtil.getReader(cdaMapFile, "Sheet1");

        HashMap<String, String> incrementMap = new HashMap<>();

        List<Map<String, Object>> maps = reader.readAll();

        for (Map<String, Object> map : maps) {
            String describe = (String) map.get("cda");
            String attribute = (String) map.get("attribute");
            String path = (String) map.get("path");
            if (path == null || path.equals("")) {
                continue;
            }

            incrementMap.put(describe, attribute.concat("#@#").concat(path));
        }

        reader.close();

        for (String sheetName : sheetNames) {
            updateOneSheet(incrementMap, excelFile, sheetName);
        }



    }

    private static void updateOneSheet(HashMap<String, String> incrementMap, File excelFile, String sheetName) {
        System.out.println(sheetName + ",开始更新字段路径");

        ExcelReader reader = ExcelUtil.getReader(excelFile, sheetName);

        List<Map<String, Object>> readAll = reader.readAll();

        // 修改数据
        for (Map<String, Object> row : readAll) {
            String shuoming = (String) row.get("说明与描述");

            String value = incrementMap.get(shuoming);
            if (!StringUtils.isNotBlank(value)) continue;
            if (value.split("#@#").length < 2) continue;
            String attribute = value.split("#@#")[0];
            String path = value.split("#@#")[1];
            if (StringUtils.isNotBlank(path)) {
                // 更新到row的对应属性
                String shuxing = (String) row.get("属性");
                String lujing = (String) row.get("路径");
                String guding = (String) row.get("是否固定值");

                int index = Arrays.asList(shuxing.split("#")).indexOf(attribute);
                if (index == -1) index = 0;

                String[] LJparts = lujing.split("\\|", -1);
                LJparts[index] = path;
                row.put("路径", String.join("|", LJparts));

                String[] GDparts = guding.split("\\|", -1);
                GDparts[index] = "2";
                row.put("是否固定值", String.join("|", GDparts));

            }
        }

        // 写回Excel文件
        ExcelWriter writer = ExcelUtil.getWriter(excelFile, sheetName.concat("_new"));
        writer.write(readAll);
        writer.close();

        System.out.println(sheetName + ",更新路径字段完毕");
    }

    private static void appendToCDAMap(HashSet<String> increment, File file, String sheetName) {
        ExcelWriter writer = ExcelUtil.getWriter(file, sheetName);

        List<Map<String, Object>> added = new ArrayList<>();
        for (String describe : increment) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("cda", describe);
            map.put("attribute", describe.contains("置于id/@extension") ? "extension" : "null");
            map.put("path", "");
            added.add(map);
        }

        writer.write(added);
        writer.close();
    }

    private static HashSet<String> getIncrement(HashSet<String> needFields, HashSet<String> cdaMaps) {

        HashSet<String> increment = new HashSet<>();

        needFields.forEach(describe -> {
            if (!cdaMaps.contains(describe)) {increment.add(describe);}
        });

        return increment;
    }

    private static HashSet<String> readCDAMap(File file, String sheetName) {
        System.out.println("开始读已配置的字段");

        HashSet<String> result = new HashSet<>();

        ExcelReader reader = ExcelUtil.getReader(file, sheetName);

        List<Map<String, Object>> maps = reader.readAll();

        for (Map<String, Object> map : maps) {
            String describe = (String) map.get("cda");
            String attribute = (String) map.get("attribute");
            String path = (String) map.get("path");
            result.add(describe);
        }

        return result;

    }

    private static void updateAttributes(File file, String sheetName) {
        System.out.println(sheetName + ",开始更新属性");

        ExcelReader reader = ExcelUtil.getReader(file, sheetName);

        List<Map<String, Object>> readAll = reader.readAll();

        // 修改数据
        for (Map<String, Object> row : readAll) {
            String shuoming = (String) row.get("说明与描述");
            StringBuilder shuxing = new StringBuilder((String) (row.get("属性") == null ? "" : row.get("属性")));
            if (shuoming != null) {
                StringBuilder paths = null;
                StringBuilder isGuDing = null;
                Map<String, String> attributes = extractAttributes(shuoming);

                String[] split = shuxing.toString().split("#");
                for (String s : attributes.keySet()) {
                    if (!Arrays.asList(split).contains(s)) {
                        shuxing.append("#").append(s);
                    }
                }

                if (shuoming.contains("@extension") && !shuxing.toString().contains("extension")){
                    shuxing.append("#").append("extension");
                }

                row.put("属性", shuxing.toString());

                if (attributes.isEmpty() || StringUtils.isEmpty(shuxing.toString())) {
                    continue;
                }

                for (String name : shuxing.toString().split("#")) {
                    String value = attributes.getOrDefault(name, "");
                    String type = StringUtils.isBlank(value) ? "" : "1";
                    if (paths != null) {
                        paths.append("|").append(value);
                        isGuDing.append("|").append(type);
                    } else {
                        paths = new StringBuilder(value);
                        isGuDing = new StringBuilder(type);
                    }
                }
                row.put("路径", paths.toString());
                row.put("是否固定值", isGuDing.toString());
            }
        }

        // 写回Excel文件
        ExcelWriter writer = ExcelUtil.getWriter(file, sheetName);
        writer.write(readAll);
        writer.close();

        System.out.println(sheetName + ",更新属性完毕");
    }

    public static Map<String, String> extractAttributes(String text) {
        Map<String, String> map = new HashMap<>();
        // 定义正则表达式模式
//        String regex = "@(\\w+)=\"([^\"]+)\"";
        String regex = "@([\\w:]+)=\"([^\"]+)\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);

        // 查找匹配项
        while (matcher.find()) {
            String attribute = matcher.group(1); // xxx
            String value = matcher.group(2); // yyy
            map.put(attribute, value);
        }

        return map;
    }

    // 查excel中数据源标识符不为空，且说明字段描述了需要填什么内容的元素
    private static void findNeedField(File file, String sheetName, HashSet<String> result) {
        System.out.println(sheetName + ",开始查需要配置字段的元素");

        ExcelReader reader = ExcelUtil.getReader(file, sheetName);

        List<Map<String, Object>> readAll = reader.readAll();

        // 修改数据
        for (Map<String, Object> row : readAll) {
            String fieldFlag = (String) row.get("数据源标识符");
            String describe = (String) row.get("说明与描述");

            if ((!StringUtils.isBlank(fieldFlag)) &&
                    (!describe.isEmpty()) &&
                    (!describe.startsWith("其中， @")) &&
                    (!describe.startsWith("其中，@")) &&
                    (!describe.startsWith("其中， @")) &&
                    (!describe.startsWith("其中@")) &&
                    (!describe.startsWith("其中缺省值， @")) &&
                    (!describe.startsWith("其 中 缺 省 值 ，@")) &&
                    (!describe.startsWith("其中缺省值@")) &&
                    (!describe.startsWith("O其中， @")) &&
                    (!describe.startsWith("其 中 ，@")) &&
                    (!describe.startsWith("其中缺省值，@")) &&
                    (!describe.startsWith("@")) &&
                    (!describe.startsWith("缺省值@"))
            ) {
                result.add(describe);
            }

        }

        System.out.println(sheetName + ",查需要配置字段的元素,结束");

    }

}
